﻿using Dycox.Drawing;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;

namespace Dycox.Reporting
{
    internal static class ReportPaint
    {
        public static SizeF MeasureText(RenderingContext context, string text, ElementStyle style)
        {
            Font font;

            if (style == null || style.Font == null)
                font = SystemFonts.DefaultFont;
            else
                font = style.Font.CreateFont();

            using (font)
            {
                return context.Graphics.MeasureString(text, font);
            }
        }

        public static void RenderBackground(RenderingContext context, RectangleF bounds, BackgroundStyle style)
        {
            FillStyle fill = style.FillStyle;
            Brush brush;
            Color color1 = style.FillColor;

            if (fill != FillStyle.None && !color1.IsEmpty)
            {
                switch (fill)
                {
                    case FillStyle.None:
                        brush = null;
                        break;
                    case FillStyle.Solid:
                        brush = new SolidBrush(color1);
                        break;
                    case FillStyle.Hatch:
                        brush = new HatchBrush(style.HatchStyle, color1, style.AlternativeColor);
                        break;
                    default:
                        throw new NotSupportedException("FillStyle " + fill + " is not supported.");
                }

                if (brush != null)
                {
                    try
                    {
                        context.Graphics.FillRectangle(brush, bounds);
                    }
                    finally
                    {
                        brush.Dispose();
                    }
                }
            }
        }

        public static void RenderBorders(RenderingContext context, RectangleF bounds, BorderStyle style)
        {
            RenderBorders(context, bounds, style, BorderSides.All);
        }

        public static void RenderBorders(RenderingContext context, RectangleF bounds, BorderStyle style, BorderSides sides)
        {
            float width = style.LineWidth;
            Color color = style.LineColor;

            if (width > 0f && !color.IsEmpty)
            {
                float radius = style.CornerRadius;
                Graphics _graphics = context.Graphics;

                using (Pen pen = new Pen(color, width))
                {
                    pen.DashStyle = style.DashStyle;
                    //pen.Alignment = PenAlignment.Inset;
                    //bounds.Width -= width / 2f;
                    //bounds.Height -= width / 2f;
                    if (float.IsNaN(radius) || sides != BorderSides.All)
                    {
                        if (sides != BorderSides.All)
                        {
                            float left = bounds.Left,
                                top = bounds.Top,
                                right = bounds.Right ,
                                bottom = bounds.Bottom ;

                            if ((sides & BorderSides.Top) == BorderSides.Top)
                                _graphics.DrawLine(pen, left, top, right, top);
                            if ((sides & BorderSides.Right) == BorderSides.Right)
                                _graphics.DrawLine(pen, right, top, right, bottom);
                            if ((sides & BorderSides.Bottom) == BorderSides.Bottom)
                                _graphics.DrawLine(pen, right, bottom, left, bottom);
                            if ((sides & BorderSides.Left) == BorderSides.Left)
                                _graphics.DrawLine(pen, left, bottom, left, top);
                        }
                        else
                            _graphics.DrawRectangle(pen, bounds.Left, bounds.Top, bounds.Width, bounds.Height );
                    }
                    else
                    {
                        using (GraphicsPath path = GdiHelpers.CreateRoundedCornerPath(bounds.X, bounds.Y, bounds.Width - width / 2f, bounds.Height - width / 2f, radius))
                        {
                            _graphics.DrawPath(pen, path);
                        }
                    }
                }

            }
        }

        public static void DrawString(RenderingContext context, string text, RectangleF bounds, ElementStyle style)
        {
            Color color = style.ForeColor;

            if (!string.IsNullOrEmpty(text) && !color.IsEmpty)
            {
                StringFormat fmt = new StringFormat();
                StringAlignment align;
                HorizontalAlignment halign = style.HorizontalAlignment;
                VerticalAlignment valign = style.VerticalAlignment;

                if (halign == HorizontalAlignment.Center)
                    align = StringAlignment.Center;
                else if (halign == HorizontalAlignment.Right)
                    align = StringAlignment.Far;
                else
                    align = StringAlignment.Near;

                fmt.Alignment = align;

                if (valign == VerticalAlignment.Middle)
                    align = StringAlignment.Center;
                else if (valign == VerticalAlignment.Bottom)
                    align = StringAlignment.Far;
                else
                    align = StringAlignment.Near;
                fmt.LineAlignment = align;

                SolidBrush brush = new SolidBrush(color);
                Font font = style.Font.CreateFont();

                context.Graphics.DrawString(text, font, brush, bounds, fmt);

                font.Dispose();
                brush.Dispose();
                fmt.Dispose();
            }
        }
    }

    public enum BorderSides
    {
        None = 0,
        Top = 1,
        Right = 2,
        Bottom = 4,
        Left = 8,
        All = Top | Right | Bottom | Left,
        HSides = Left | Right,
        VSides = Top | Bottom

    }

}
